package com.csaba.swing.gui.util;

import java.awt.Component;
import java.awt.Rectangle;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.csaba.util.LoggerHelper;

public class WindowSizeContanier implements ComponentListener
{
	private final static Logger logger = LoggerHelper.getDefaultLogger();

	private static WindowSizeContanier instance = new WindowSizeContanier();

	public final static WindowSizeContanier getInstance()
	{
		return instance;
	}

	/**
	 * This hashmap will store one position/dimension for one window class.
	 */
	HashMap<String, Rectangle> store = new HashMap<String, Rectangle>();

	private WindowSizeContanier()
	{
	}

	public void parseString( final String init )
	{
		try
		{
			final HashMap<String, Rectangle> newStore = new HashMap<String, Rectangle>();
			final StringTokenizer commas = new StringTokenizer(init, ";");
			while ( commas.hasMoreTokens() )
			{
				final String classDesc = commas.nextToken();
				final int begin = classDesc.indexOf('[');
				final String className = classDesc.substring(0, begin);
				final StringTokenizer coordinates = new StringTokenizer(classDesc.substring(begin + 1, classDesc
						.length() - 1), ",");
				final Rectangle bounds = new Rectangle();
				bounds
						.setLocation(Integer.parseInt(coordinates.nextToken()), Integer.parseInt(coordinates
								.nextToken()));
				bounds.setSize(Integer.parseInt(coordinates.nextToken()), Integer.parseInt(coordinates.nextToken()));

				newStore.put(className, bounds);
			}

			store = newStore;
		}
		catch ( final Exception ex )
		{
			logger.log(Level.SEVERE, "Error loading configuration for window sizes. \n" + init, ex);
		}

	}

	@Override
	public String toString()
	{
		final StringBuilder output = new StringBuilder();
		for ( final String className : store.keySet() )
		{
			final Rectangle bounds = store.get(className);
			if ( output.length() > 0 )
				output.append(";");
			output.append(className);
			output.append('[');
			output.append(bounds.x).append(',');
			output.append(bounds.y).append(',');
			output.append(bounds.width).append(',');
			output.append(bounds.height);
			output.append(']');
		}
		return output.toString();
	}

	private void componentChanged( final Component comp )
	{
		final Rectangle bounds = comp.getBounds();
		final String className = comp.getClass().getName();
		final Rectangle old = store.put(className, bounds);
		if ( old == null )
			logger.fine("New window is registered: " + className);

	}

	public boolean monitorComponent( final Component comp )
	{
		final String className = comp.getClass().getName();
		comp.addComponentListener(this);
		if ( store.containsKey(className) )
		{
			comp.setBounds(store.get(className));
			return true;
		}
		else
		{
			store.put(className, comp.getBounds());
			return false;
		}
	}

	public void componentHidden( final ComponentEvent arg0 )
	{
		// do nothing
	}

	public void componentMoved( final ComponentEvent arg0 )
	{
		componentChanged(arg0.getComponent());
	}

	public void componentResized( final ComponentEvent arg0 )
	{
		componentChanged(arg0.getComponent());
	}

	public void componentShown( final ComponentEvent arg0 )
	{
		// do nothing
	}

}
